package com.powerteam.service.masterData.Impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.powerteam.exception.BusinessException;
import com.powerteam.mapper.masterData.OrgUnitMapper;
import com.powerteam.model.masterData.OrgUnit;
import com.powerteam.model.masterData.OrgUnitUser;
import com.powerteam.model.sys.User;
import com.powerteam.service.masterData.OrgUnitService;
import com.powerteam.vo.Result;
import com.powerteam.vo.masterData.QueryOrgUnitUserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 组织架构相关服务接口实现
 *
 * @author jinming.zhang
 * @version 0.0.1
 * @date 2021/12/30
 */
@Slf4j
@Service
public class OrgUnitServiceImpl implements OrgUnitService {

    private static final String CLASS_NAME = "OrgUnitServiceImpl";

    @Autowired
    private OrgUnitMapper orgUnitMapper;

    @Override
    public List<Integer> findSubordinate(Integer userId) {

        try {

            // 查询下级列表
            List<Integer> subordinate = orgUnitMapper.findSubordinate(userId);
            log.info("{} findSubordinate 查询下级列表 入参0:{}, 结果0:{}", CLASS_NAME, userId, JSON.toJSON(subordinate));

            if (CollectionUtils.isEmpty(subordinate)) {
                subordinate.add(userId);
            }

            return subordinate;
        } catch (Exception e) {
            log.warn("{} findSubordinate 查询下级列表异常 入参0:{}", CLASS_NAME, userId);
            log.error(e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    @Override
    public List<OrgUnit> findAllOrgUnit() {

        try {
            List<OrgUnit> allOrgUnit = orgUnitMapper.findAllOrgUnit();
            log.info("{} findAllOrgUnit 查找所有组织单位 结果0:{}", CLASS_NAME, JSON.toJSON(allOrgUnit));

            return allOrgUnit;
        } catch (Exception e) {
            log.warn("{} findAllOrgUnit 查找所有组织单位异常", CLASS_NAME);
            log.error(e.getMessage(), e);
            return new ArrayList<>();
        }
    }

    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result insert(OrgUnit orgUnit) {

        try {

            // 查询是否存在根组织
            boolean rootOrgUnit = orgUnitMapper.existRootOrgUnit();
            log.info("{} insert 查询是否存在根组织 结果0:{}", CLASS_NAME, rootOrgUnit);

            // 如果存在且没有上级Id 说明是根组织
            if (StringUtils.isEmpty(orgUnit.getPid()) && rootOrgUnit) {
                return new Result(false, "只能有一个根节点");
            }

            // 查找最大组织
            Integer maxOrgIndex = orgUnitMapper.findMaxOrgIndex();
            log.info("{} insert 查找最大组织 结果0:{}", CLASS_NAME, maxOrgIndex);

            // 添加组织架构信息
            orgUnit.setOrgIndex(maxOrgIndex + 1);
            boolean result = orgUnitMapper.insert(orgUnit) > 0;
            log.info("{} insert 添加组织架构信息 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(orgUnit), result);

            return new Result(result);
        } catch (Exception e) {
            log.warn("{} insert 添加组织架构信息异常 入参0:{}", CLASS_NAME, JSON.toJSON(orgUnit));
            log.error(e.getMessage(), e);
            throw new BusinessException("添加组织架构失败");
        }
    }

    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result update(OrgUnit orgUnit) {

        try {
            // 查询是否存在根组织
            boolean rootOrgUnit = orgUnitMapper.existRootOrgUnit();
            log.info("{} update 查询是否存在根组织 结果0:{}", CLASS_NAME, rootOrgUnit);

            // 如果存在且没有上级Id 说明是根组织
            if (StringUtils.isEmpty(orgUnit.getPid()) && rootOrgUnit) {
                return new Result(false, "只能有一个根节点");
            }
            // 修改组织架构信息
            boolean result = orgUnitMapper.update(orgUnit) > 0;
            log.info("{} update 修改组织架构信息 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(orgUnit), result);

            return new Result(result);
        } catch (Exception e) {
            log.warn("{} update 修改组织架构信息异常 入参0:{}", CLASS_NAME, JSON.toJSON(orgUnit));
            log.error(e.getMessage(), e);
            throw new BusinessException("修改组织架构错误");
        }

    }

    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result delete(Integer orgUnitId) {

        // 查找下级组织 如果存在, 则提示先删除下级组织
        OrgUnit orgUnit = orgUnitMapper.existChildren(orgUnitId);
        if (!ObjectUtils.isEmpty(orgUnit)) {
            throw new BusinessException("存在下级组织");
        }

            try {

                boolean result = orgUnitMapper.deleteWithChildren(orgUnitId) > 0;
                log.info("{} delete 删除组织架构信息 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(orgUnitId), result);

                return new Result(result);
            } catch (Exception e) {
                log.warn("{} delete 删除组织架构信息异常 入参0:{}", CLASS_NAME, JSON.toJSON(orgUnitId));
                log.error(e.getMessage(), e);
                throw new BusinessException("删除组织架构错误");
            }

    }

    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result up(Integer orgUnitId) {

        try {
            // 查找上一个组织架构
            OrgUnit orgUnit = orgUnitMapper.findPreviousUnit(orgUnitId);
            log.info("{} up 查找上一个组织架构 入参0:{} 结果0:{}", CLASS_NAME, orgUnitId, JSON.toJSON(orgUnit));

            // 调动组织架构
            return moveOrgUnit(orgUnitId, orgUnit);
        } catch (Exception e) {
            log.warn("{} up 上调组织架构异常 入参0:{}", CLASS_NAME, orgUnitId);
            log.error(e.getMessage(), e);
            throw new BusinessException("上调组织架构失败");
        }
    }

    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result down(Integer orgUnitId) {

        try {
            // 查找下一个组织架构
            OrgUnit orgUnit = orgUnitMapper.findNextUnit(orgUnitId);
            log.info("{} down 查找下一个组织架构 入参0:{} 结果0:{}", CLASS_NAME, orgUnitId, JSON.toJSON(orgUnit));

            // 调动组织架构
            return moveOrgUnit(orgUnitId, orgUnit);
        } catch (Exception e) {
            log.warn("{} down 下调组织架构异常 入参0:{}", CLASS_NAME, orgUnitId);
            log.error(e.getMessage(), e);
            throw new BusinessException("下调组织架构失败");
        }
    }

    /**
     * 上/下移动组织结构
     *
     * @param orgUnitId 当前组织架构Id 移动的组织架构信息
     * @param orgUnit
     * @return
     */
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result moveOrgUnit(Integer orgUnitId, OrgUnit orgUnit) {

        try {

            if (!ObjectUtils.isEmpty(orgUnit) && !StringUtils.isEmpty(orgUnitId)) {
                // 查询当前组织架构
                OrgUnit unit = orgUnitMapper.findById(orgUnitId);
                log.info("{} moveOrgUnit 查询当前组织架构 入参0:{} 结果0:{}", CLASS_NAME, orgUnitId, JSON.toJSON(unit));

                // 当前组织架构
                int tempIndex = unit.getOrgIndex();
                // 当前组织架构Id设置为上一个;上一个组织架构Id设置为当前;实现移动操作
                unit.setOrgIndex(orgUnit.getOrgIndex());
                orgUnit.setOrgIndex(tempIndex);

                // 上/下移动组织结构
                if (!this.update(unit).isSuccess() || !this.update(orgUnit).isSuccess()) {
                    throw new BusinessException();
                }
            }

            return new Result(true);
        } catch (Exception e) {
            log.warn("{} moveOrgUnit 上/下移动组织结构异常 入参0:{} 1:{}", CLASS_NAME, orgUnitId, JSON.toJSON(orgUnit));
            log.error(e.getMessage(), e);
            throw new BusinessException("上/下移动组织结构失败");
        }
    }

    @Override
    public PageInfo<User> findUserNotInOrgUnit(QueryOrgUnitUserVO vo) {

        try {

            // 处理参数
            this.disposeParameter(vo);
            // 分页查找不在该组织单位中的用户
            List<User> userNotInOrgUnit = orgUnitMapper.findUserNotInOrgUnit(vo);
            log.info("{} findUserNotInOrgUnit 分页查找不在该组织单位中的用户 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(vo), JSON.toJSON(userNotInOrgUnit));

            return new PageInfo<>(userNotInOrgUnit);
        } catch (Exception e) {
            log.warn("{} findUserNotInOrgUnit 分页查找不在该组织单位中的用户异常 入参0:{}", CLASS_NAME, JSON.toJSON(vo));
            log.error(e.getMessage(), e);
            return new PageInfo<>(new ArrayList<>());
        }
    }

    @Override
    public PageInfo<OrgUnitUser> findUserInOrgUnit(QueryOrgUnitUserVO vo) {

        try {

            // 处理参数
            this.disposeParameter(vo);
            // 分页查找该组织单位中的用户
            List<OrgUnitUser> userInOrgUnit = orgUnitMapper.findUserInOrgUnit(vo);
            log.info("{} findUserInOrgUnit 分页查找该组织单位中的用户 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(vo), JSON.toJSON(userInOrgUnit));

            return new PageInfo<>(userInOrgUnit);
        } catch (Exception e) {
            log.warn("{} findUserInOrgUnit 分页查找该组织单位中的用户异常 入参0:{}", CLASS_NAME, JSON.toJSON(vo));
            log.error(e.getMessage(), e);
            return new PageInfo<>(new ArrayList<>());
        }
    }

    /**
     * 处理参数
     *
     * @param vo
     */
    private void disposeParameter(QueryOrgUnitUserVO vo) {

        // 分页 如果不是禁用分页 设置分页条件
        if (StringUtils.isEmpty(vo.getDisablePaging()) || !vo.getDisablePaging()) {
            PageHelper.startPage(vo.getPageNum(), vo.getPageSize());
        }

        // 模糊匹配
        vo.setWord(StringUtils.isEmpty(vo.getWord()) ? null : "%".concat(vo.getWord()).concat("%"));
    }

    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result insertOrgUnitUser(OrgUnitUser orgUnitUser) {

        try {

            // 将用户添加到组织单位
            orgUnitUser.setIsUnitHead(false);
            boolean result = orgUnitMapper.insertOrgUnitUser(orgUnitUser) > 0;
            log.info("{} insertOrgUnitUser 将用户添加到组织单位 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(orgUnitUser), result);

            return new Result(result);
        } catch (Exception e) {
            log.warn("{} insertOrgUnitUser 将用户添加到组织单位异常 入参0:{}", CLASS_NAME, JSON.toJSON(orgUnitUser));
            log.error(e.getMessage(), e);
            throw new BusinessException("添加到组织单位失败");
        }

    }

    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result deleteOrgUnitUser(OrgUnitUser orgUnitUser) {

        try {

            // 将用户从该组织单位移除
            boolean result = orgUnitMapper.deleteOrgUnitUser(orgUnitUser) > 0;
            log.info("{} deleteOrgUnitUser 将用户从该组织单位移除 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(orgUnitUser), result);

            return new Result(result);
        } catch (Exception e) {
            log.warn("{} deleteOrgUnitUser 将用户从该组织单位移除异常 入参0:{}", CLASS_NAME, JSON.toJSON(orgUnitUser));
            log.error(e.getMessage(), e);
            throw new BusinessException("移除失败");
        }
    }

    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result setUnitHead(OrgUnitUser orgUnitUser) {

        try {

            // 移除当前组织单位的主管
            if (this.removeUnitHead(orgUnitUser).isSuccess()) {
                // 将用户设置为主管
                boolean result = orgUnitMapper.setUnitHead(orgUnitUser) > 0;
                log.info("{} setUnitHead 将用户设置为主管 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(orgUnitUser), result);

                return new Result(result);
            } else {
                throw new BusinessException("设为主管失败");
            }
        } catch (BusinessException e) {
            log.warn("{} setUnitHead 将用户设置为主管异常 入参0:{}", CLASS_NAME, JSON.toJSON(orgUnitUser));
            log.error(e.getMessage(), e);
            throw new BusinessException("设为主管失败");
        }

    }

    @Override
    @Transactional(rollbackFor = {BusinessException.class}, propagation = Propagation.REQUIRED)
    public Result removeUnitHead(OrgUnitUser orgUnitUser) {

        try {

            // 移除当前组织单位的主管
            boolean result = orgUnitMapper.removeUnitHead(orgUnitUser) > 0;
            log.info("{} removeUnitHead 移除当前组织单位的主管 入参0:{} 结果0:{}", CLASS_NAME, JSON.toJSON(orgUnitUser), result);

            return new Result(result);
        } catch (Exception e) {
            log.info("{} removeUnitHead 移除当前组织单位的主管异常 入参0:{}", CLASS_NAME, JSON.toJSON(orgUnitUser));
            log.error(e.getMessage(), e);
            throw new BusinessException("解除主管失败");
        }

    }

}
